﻿using System;
using System.Data.Services.Client;
using System.Linq;
using System.Windows;
using Microsoft.Phone.Shell;
using Tfs.OnTheRoad.Model;
namespace Tfs.OnTheRoad.ViewModel
{
    /// <summary>
    /// Work Items Chart ViewModel
    /// </summary>
    public class WorkItemsChartViewModel : BaseViewModel
    {
        public WorkItemsChartViewModel() : this(null, null, null) { }
        public WorkItemsChartViewModel(string[] workItemTypes, string[] states)
            : this(null, workItemTypes, states)
        {
        }
        public WorkItemsChartViewModel(Query currentQuery, string[] types)
            : this(currentQuery, types, null)
        {
        }
        private string _summaryEntity = string.Empty;
        public WorkItemsChartViewModel(Query currentQuery, string[] types, string[] states)
            : base()
        {
            CurrentQuery = currentQuery;
            _workItemsSummary = new WorkItemsSummaryList();
            System.Text.StringBuilder additionalQueryParameters = new System.Text.StringBuilder();
            var currentProject = PhoneApplicationService.Current.State["CurrentProject"] as Project;
            if (currentQuery != null)
            {
                _summaryEntity = string.Format("Queries('{0}')/WorkItems?$select=Type,State", CurrentQuery.Id);
            }
            else
            {
                if (states != null && states.Length>0)
                {                    
                    foreach (string state in states)
                        additionalQueryParameters.AppendFormat("State eq '{0}' or ", state);
                    additionalQueryParameters.Remove(additionalQueryParameters.Length - 4, 4);//4 = ' Or '
                    //Coming from drill down of the project overview. Only one type!(Types[0])
                    _summaryEntity = string.Format("Projects('{0}')/WorkItems?$select=Type,State&$filter=Type eq '{1}' and ({2})", currentProject.Name,types[0], additionalQueryParameters.ToString());
                }
                else
                    _summaryEntity = string.Format("Projects('{0}')/WorkItems?$select=Type,State", currentProject.Name);                
            }
           
        }

        private bool _processing;

        public bool Processing
        {
            get { return _processing; }
            set
            {
                _processing = value;
                this.RaisePropertyChanged("Processing");
            }
        }

        bool summaryLoaded = false;
        public void CalculateSummary()
        {
            if (!summaryLoaded)
            {
                DataServiceCollection<WorkItem> workItemsSummary;
                var context = App.CreateTfsDataServiceContext();
                workItemsSummary = new DataServiceCollection<WorkItem>(context);
                workItemsSummary.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(summary_LoadCompleted);
                workItemsSummary.LoadAsync(new Uri(_summaryEntity, UriKind.Relative));
                Processing = true;
                summaryLoaded = true;
            }
        }

        public event EventHandler ChartDataPrepared;

        void summary_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
            DataServiceCollection<WorkItem> workItemsSummary = sender as DataServiceCollection<WorkItem>;
            if (!e.Cancelled && workItemsSummary != null)
            {
                WorkItemsSummary.Clear();
                //getting all workItem types(will be used by the WorkItemsOverviewPage page)
                var wiTypesQuery = (from wi in workItemsSummary
                                    select wi.Type).Distinct();
                PhoneApplicationService.Current.State["WorkItemsTypes"] = wiTypesQuery.ToArray();

                //Getting state groups
                WorkItemsCount = workItemsSummary.Count;
                var wiTypesSummaryState = from wi in workItemsSummary
                                          group wi by wi.State into StateGroup
                                          orderby StateGroup.Key
                                          select new { State = StateGroup.Key, Count = StateGroup.Count() };
                foreach (var stateItem in wiTypesSummaryState)
                {
                    var currentState = new WorkItemSummaryItem() { State = stateItem.State, Count = stateItem.Count };
                    _workItemsSummary.Add(currentState);
                    //Now let's build a query to group the WI Type by State
                    var wiTypeSummaryByState = from wi in workItemsSummary
                                               where string.Compare(wi.State, stateItem.State, StringComparison.OrdinalIgnoreCase) == 0
                                               group wi by wi.Type into TypeGroup
                                               where TypeGroup.Count() > 0
                                               select new { Type = TypeGroup.Key, Count = TypeGroup.Count() };
                    foreach (var typeGroup in wiTypeSummaryByState)
                        currentState.Types.Add(new WorkItemSummaryItem.StateSummaryItem() { Parent = currentState, Type = typeGroup.Type, Count = typeGroup.Count });
                }
                if (ChartDataPrepared != null)
                    ChartDataPrepared(this, EventArgs.Empty);
            }
            else 
            {
                if(e.Error != null)
                    MessageBox.Show(e.Error.Message);
            }
            Processing = false;
        }

        private int _workItemsCount;

        public int WorkItemsCount
        {
            get { return _workItemsCount; }
            set
            {
                _workItemsCount = value;
                this.RaisePropertyChanged("WorkItemsCount");
            }
        }

        private WorkItemsSummaryList _workItemsSummary;
        public WorkItemsSummaryList WorkItemsSummary
        {
            get { return _workItemsSummary; }
        }

        private Query _currentQuery;

        public Query CurrentQuery
        {
            get { return _currentQuery; }
            set { _currentQuery = value; }
        }            
    }
}
